package com.aps.demo;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * 产品时间区间类
 * 
 * 在APS排程系统中，一个工序通常需要加工多个产品单位。
 * 该类用于记录单个产品在特定工序中的加工时间区间。
 * 
 * 业务场景：
 * - 订单J1有20个产品，工序J1-1需要加工这20个产品
 * - 每个产品的加工都有独立的开始时间和结束时间
 * - 便于跟踪生产进度和资源占用情况
 * 
 * @author APS System
 * @version 1.0
 */
public class ProductInterval {
    
    /** 时间格式化器 */
    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
    
    /** 产品序号（在该工序中的第几个产品，从1开始） */
    private int productIndex;

    public List<Operation.TimeInterval> getOvertimeIntervals() {
        return overtimeIntervals;
    }

    public void setOvertimeIntervals(List<Operation.TimeInterval> overtimeIntervals) {
        this.overtimeIntervals = overtimeIntervals;
    }

    /** 该产品在此工序的开始加工时间 */
    private LocalDateTime start;
    
    /** 该产品在此工序的完成时间 */
    private LocalDateTime end;
    List<Operation.TimeInterval> overtimeIntervals = new ArrayList<>(); // 该产品在本工序的加班时间
    /**
     * 构造函数
     * 
     * @param productIndex 产品序号（从1开始）
     * @param start 开始时间
     * @param end 结束时间
     */
    public ProductInterval(int productIndex, LocalDateTime start, LocalDateTime end) {
        this.productIndex = productIndex;
        this.start = start;
        this.end = end;
    }
    
    // Getter和Setter方法
    
    /**
     * 获取产品序号
     * 
     * @return 产品序号
     */
    public int getProductIndex() {
        return productIndex;
    }
    
    /**
     * 设置产品序号
     * 
     * @param productIndex 产品序号
     */
    public void setProductIndex(int productIndex) {
        this.productIndex = productIndex;
    }
    
    /**
     * 获取开始时间
     * 
     * @return 开始时间
     */
    public LocalDateTime getStart() {
        return start;
    }
    
    /**
     * 设置开始时间
     * 
     * @param start 开始时间
     */
    public void setStart(LocalDateTime start) {
        this.start = start;
    }
    
    /**
     * 获取结束时间
     * 
     * @return 结束时间
     */
    public LocalDateTime getEnd() {
        return end;
    }
    
    /**
     * 设置结束时间
     * 
     * @param end 结束时间
     */
    public void setEnd(LocalDateTime end) {
        this.end = end;
    }
    
    /**
     * 计算该产品的加工时长（分钟）
     * 
     * @return 加工时长（分钟）
     */
    public long getProcessingTimeInMinutes() {
        return java.time.Duration.between(start, end).toMinutes();
    }
    
    /**
     * 检查该时间区间是否与另一个时间区间有重叠
     * 
     * @param other 另一个时间区间
     * @return 如果有重叠返回true，否则返回false
     */
    public boolean overlaps(ProductInterval other) {
        return !(this.end.isBefore(other.start) || this.start.isAfter(other.end));
    }
    
    /**
     * toString方法，便于调试和日志输出
     * 
     * @return 格式化的字符串表示
     */
    @Override
    public String toString() {
        return String.format("产品%d: %s ~ %s (%d分钟)", 
                productIndex, 
                start.format(formatter), 
                end.format(formatter),
                getProcessingTimeInMinutes());
    }
}
